﻿using RndMaterialDisposalService.Attrbutes;
using RndMaterialDisposalService.Models;
using RndMaterialDisposalService.Models.Entitys;
using RndMaterialDisposalService.Models.RequestModel;
using RndMaterialDisposalService.Repository;
using RndMaterialDisposalService.Services.Interface.ValidationProblemTracking;
using Masuit.Tools;
using Masuit.Tools.Core.AspNetCore;
using Microsoft.EntityFrameworkCore;
using RndMaterialDisposalService.Extensions;
using ValidationProblemTracking.Models.ResponseModel;
using Microsoft.Data.SqlClient;

namespace RndMaterialDisposalService.Services.ValidationProblemTracking
{
    /// <summary>
    /// 
    /// </summary>
    [NAutowired]
    public class LaunchVerifyService : ILaunchVerifyService
    {

        private readonly ILogger<LaunchVerifyService> logger;
        private readonly WorkflowCommonDataContext commonDataContext;
        private readonly AssetsManagementContext assetsManagementContext;


        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="assetsManagementContext"></param>
        /// <param name="commonDataContext"></param>
        public LaunchVerifyService(ILogger<LaunchVerifyService> logger, AssetsManagementContext assetsManagementContext, WorkflowCommonDataContext commonDataContext)
        {
            this.logger = logger;
            this.assetsManagementContext = assetsManagementContext;
            this.commonDataContext = commonDataContext;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="procInstId"></param>
        /// <returns></returns>
        public async Task<NewProductApplyReportDto> GetProductApplyReportData(string procInstId)
        {
            var data = await assetsManagementContext.NewProductApplyReport.FirstOrDefaultAsync(p=>p.ProcInstId== procInstId);
            return data ?? new NewProductApplyReportDto(); 
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="procInstId"></param>
        /// <returns></returns>
        public async Task<List<ERPDeviceInfoReportDto>> NewProductApplyERPDeviceInfoReport(string procInstId)
        {
            var data = await assetsManagementContext.NewProductApplyERPDeviceInfoReport.Where(p => p.ProcInstId == procInstId).ToListAsync();
            return data ?? new List<ERPDeviceInfoReportDto>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="reportModel"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> SaveReportData(LaunchVerifyReportDto reportModel)
        {
            assetsManagementContext.LaunchVerifyReport.AddOrUpdate(p => p.ProcInstId, reportModel);
            return await assetsManagementContext.SaveChangesAsync();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="inputReq"></param>
        /// <returns></returns>
        public async Task<(List<LaunchVerifyReportDto> list, int count)> GetReportData(LaunchVerifyReportDataReq inputReq)
        {
            var list = assetsManagementContext.LaunchVerifyReport.Where(p => 1 == 1);
            if (!string.IsNullOrEmpty(inputReq.Subject))
            {
                list = list.Where(p => !string.IsNullOrEmpty(p.Subject) && p.Subject.Contains(inputReq.Subject));
            }
            if (!string.IsNullOrEmpty(inputReq.RelationFolio))
            {
                list = list.Where(p => !string.IsNullOrEmpty(p.RelationFolio) && p.RelationFolio.Contains(inputReq.RelationFolio));
            }
            if (!string.IsNullOrEmpty(inputReq.Applicant))
            {
                list = list.Where(p => p.Applicant == inputReq.Applicant);
            }
            if (!string.IsNullOrEmpty(inputReq.ProjectName))
            {
                list = list.Where(p => !string.IsNullOrEmpty(p.ProjectName) && p.ProjectName.Contains(inputReq.ProjectName));
            }
            if (!string.IsNullOrEmpty(inputReq.ProductLine))
            {
                list = list.Where(p => !string.IsNullOrEmpty(p.ProductLine) && p.ProductLine.Contains(inputReq.ProductLine));
            }
            if (inputReq.ProjectStartDate != null )
            {
                list = list.Where(p => p.ProjectStartDate >= inputReq.ProjectStartDate );
            }
            if (inputReq.ProjectEndDate != null)
            {
                list = list.Where(p => p.ProjectEndDate <= inputReq.ProjectEndDate);
            }


            //处理当前节点名称
            var procinstIdList = list.Select(p => $"{p.ProcInstId}".Trim()).ToList();
            var result2 = await commonDataContext.ApplicationData.Where(p => procinstIdList.Contains(p.ProcInstId!.Trim())).ToListAsync();
            list.ForEach(item =>
            {
                var procItem = result2.Where(p => p.ProcInstId!.Trim() == item.ProcInstId!.Trim());
                if (procItem.Any())
                {
                    item.ActivityName = procItem.First().CurrentStatus?.Trim();
                    item.CurrentUser = procItem.First().CurrentHandler?.Trim();
                }
            });

            var newlist = await list.ToListAsync();
            if (!string.IsNullOrEmpty(inputReq.ActivityName))
            {
                newlist = newlist.Where(p => p.ActivityName == inputReq.ActivityName).ToList();
            }


            //普通用户报表
            if (!string.IsNullOrEmpty(inputReq.CurrentUser))
            {
                var folioList = await commonDataContext.ApplicationApproveData
                    .Where(p => "中试验证启动表".Equals(p.WorkflowName!.Trim()) && inputReq.CurrentUser == p.ApproverName!.Trim())
                    .Select(p => p.ApplicationNumber!.Trim())
                    .Distinct()
                    .ToListAsync();
                newlist = newlist.Where(p => folioList.Contains(p.Folio!.Trim())).ToList();
            }

            var count = newlist.Count();
            var data = newlist.OrderByDescending(p => p.ApplicantDate)
                .Skip((inputReq.PageIndex - 1) * inputReq.PageSize)
                .Take(inputReq.PageSize).ToList();
            return (data, count);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="folio"></param>
        /// <returns></returns>
        public async Task<List<ValidationProblemResp>> ValidationProblemVerifyStartFolio(string folio) {
            var sql = @$"SELECT vpbd.ProcInstId,vpbd.Description,vpbd.Task1ProblemStatus as ProblemStatus,wad.WorkflowName,
                            TRIM(WAD.ApplicationNumber)AS ApplicationNumber,wad.ApplicantName,
                            wad.CurrentStatus,TRIM(wad.CurrentHandler)as CurrentHandler,
                            CASE WHEN COALESCE(vpbd.Task4ProblemPositioning,'')<>'' THEN vpbd.Task4ProblemPositioning 
                            WHEN COALESCE(vpbd.Task3ProblemPositioning,'')<>'' THEN vpbd.Task3ProblemPositioning
                            WHEN COALESCE(vpbd.ProblemDecide,'')<>'' THEN vpbd.ProblemDecide
                            ELSE '' END  AS ProblemLocation
                        FROM ValidationProblemTracking.dbo.ValidationProblemBusinessData vpbd 
                        JOIN VW_Common.dbo.WorkflowApplicationData wad ON vpbd.ProcInstId=wad.ProcInstId 
                        WHERE vpbd.VerifyStartFolio='{folio}'";
            var eFExtension = new EFExtension();
            var data = eFExtension.SqlQuery<ValidationProblemResp>(assetsManagementContext, sql,new List<SqlParameter>());
            return data;
        }
    }
}
